package com.ophiux.pay.remote;

import cn.hutool.json.JSONUtil;
import com.ophiux.common.core.exception.APIException;
import com.ophiux.pay.config.WechatPayV3Properties;
import com.wechat.pay.java.service.payments.jsapi.JsapiService;
import com.wechat.pay.java.service.payments.jsapi.JsapiServiceExtension;
import com.wechat.pay.java.service.payments.jsapi.model.*;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;

/**
 * @desc:
 * @author: hhl
 * @date：2023/2/15 9:19
 */
@Service
public class WecahtPayRemoteService {

    @Autowired
    WechatPayV3Properties wechatPayV3Properties;
    @Autowired
    JsapiService jsapiService;
    @Autowired
    JsapiServiceExtension jsapiServiceExtension;
    @Autowired
    RefundService refundService;


    /**
     * 预支付
     * @param payAmount
     * @param orderTitle
     * @param outTradeNo
     * @param openId
     * @return
     */
    public PrepayWithRequestPaymentResponse prepay(BigDecimal payAmount, String orderTitle, String outTradeNo, String openId) {
        PrepayRequest request = new PrepayRequest();
        Amount amount = new Amount();
        amount.setTotal(payAmount.multiply(new BigDecimal(100)).intValue());
        request.setAmount(amount);
        request.setAppid(wechatPayV3Properties.getMiniAppid());
        request.setMchid(wechatPayV3Properties.merchantId);
        request.setDescription(orderTitle);
        request.setNotifyUrl(wechatPayV3Properties.getNotifyUrl());
        request.setOutTradeNo(outTradeNo);
        Payer payer = new Payer();
        payer.setOpenid(openId);
        request.setPayer(payer);
//        PrepayResponse response = jsapiService.prepay(request);
        // response包含了调起支付所需的所有参数，可直接用于前端调起支付
        PrepayWithRequestPaymentResponse response = jsapiServiceExtension.prepayWithRequestPayment(request);
        return response;
    }


    /**
     * 查询订单支付结果
     *
     * @param outTradeNo
     * @param transactionId
     * @return
     */
    public Transaction queryOrder(String outTradeNo, String transactionId) {
        if (ObjectUtils.isEmpty(outTradeNo) && ObjectUtils.isEmpty(transactionId)) {
            throw new APIException("请输入需要查询的订单号");
        }

        if (!ObjectUtils.isEmpty(outTradeNo)) {
            QueryOrderByOutTradeNoRequest tradeNoRequest = new QueryOrderByOutTradeNoRequest();
            tradeNoRequest.setMchid(wechatPayV3Properties.merchantId);
            tradeNoRequest.setOutTradeNo(outTradeNo);
            Transaction transaction = jsapiService.queryOrderByOutTradeNo(tradeNoRequest);
            return transaction;
        } else {
            QueryOrderByIdRequest queryRequest = new QueryOrderByIdRequest();
            queryRequest.setMchid(wechatPayV3Properties.merchantId);
            queryRequest.setTransactionId(transactionId);
            Transaction transaction = jsapiService.queryOrderById(queryRequest);
            return transaction;
        }
    }

    /**
     * 关闭订单
     *
     * @param outTradeNo
     */
    public void closeOrder(String outTradeNo) {
        if (ObjectUtils.isEmpty(outTradeNo)) {
            throw new APIException("请输入订单号");
        }
        CloseOrderRequest closeRequest = new CloseOrderRequest();
        closeRequest.setMchid(wechatPayV3Properties.merchantId);
        closeRequest.setOutTradeNo(outTradeNo);
        // 方法没有返回值，意味着成功时API返回204 No Content
        jsapiService.closeOrder(closeRequest);
    }

    public void refund(String outTradeNo,String outRefundNo,BigDecimal totalAmount,BigDecimal refundAmount,String refundReason){
        CreateRequest refundRequest = new CreateRequest();
        refundRequest.setOutTradeNo(outTradeNo);
        refundRequest.setOutRefundNo(outRefundNo);
        refundRequest.setReason(refundReason);
        refundRequest.setNotifyUrl(wechatPayV3Properties.getRefundNotifyUrl());

        AmountReq amountReq = new AmountReq();
        amountReq.setRefund(refundAmount.multiply(new BigDecimal(100)).longValue());
        amountReq.setTotal(totalAmount.multiply(new BigDecimal(100)).longValue());
        amountReq.setCurrency("CNY");
        refundRequest.setAmount(amountReq);

        Refund refund = refundService.create(refundRequest);

        System.out.println(JSONUtil.toJsonStr(refund));

    }

}
